package com.labprog.oncapintada.persistencia;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.fileupload.FileItem;
import org.postgresql.jdbc3.Jdbc3Blob;

import com.labprog.oncapintada.exceptions.ClasseVaziaException;
import com.labprog.oncapintada.exceptions.ErroGeralException;
import com.labprog.oncapintada.exceptions.ProdutoNaoEncontradoException;
import com.labprog.oncapintada.exceptions.ProdutoNaoInseridoException;
import com.labprog.oncapintada.exceptions.UsuarioSemProdutoException;
import com.labprog.oncapintada.models.Classe;
import com.labprog.oncapintada.models.Produto;
import com.labprog.oncapintada.models.Usuario;

public class PersistenciaProduto extends AbstractPersistence {
	
	public void inserirProduto(Produto produto, FileItem fileItem) throws ProdutoNaoInseridoException {
		Integer count = 1;
		Connection conn = null;
		StringBuffer SQL = new StringBuffer();
		PreparedStatement stmt = null;
		SQL.append("INSERT \n");
		SQL.append("INTO    mercadex.pro_produto \n");
		SQL.append("        (\n");
		SQL.append("                pro_shortdesc,\n");
		SQL.append("                pro_preco,\n");
		SQL.append("                usu_id,\n");
		SQL.append("                pro_foto,\n");
		SQL.append("                cla_id\n");
		SQL.append("        ) \n");
		SQL.append("        VALUES \n");
		SQL.append("        (\n");
		SQL.append("                ?, \n");
		SQL.append("                ?, \n");
		SQL.append("                ?, \n");
		SQL.append("                ?, \n");
		SQL.append("                ?\n");
		SQL.append("        )");
		
		try {
			conn = super.getConnection();
			stmt = conn.prepareStatement(SQL.toString());
			
			stmt.setString(count++, produto.getDescricao());
			stmt.setDouble(count++, produto.getPreco());
			stmt.setInt(count++, produto.getVendedor().getId());
			stmt.setBinaryStream(count++, fileItem.getInputStream(),
                    (int) fileItem.getSize() );
			stmt.setInt(count++, produto.getClasse().getId());
			
			stmt.executeUpdate();
		} catch (SQLException e) {
			throw new ProdutoNaoInseridoException(produto,e);
		} catch (IOException e) {
			throw new ProdutoNaoInseridoException(produto,e);
		}
	}
	
	public List<Produto> obterProdutoPorClasse(Classe classe) throws ClasseVaziaException, ErroGeralException {
		List<Produto> retorno = new ArrayList<Produto>();
		Integer count = 1;
		Connection conn = null;
		StringBuffer SQL = new StringBuffer();
		PreparedStatement stmt = null;
		ResultSet resultSet;
		
		SQL.append("SELECT  pro.pro_id        as id, \n");
		SQL.append("        pro.pro_shortdesc as descricao, \n");
		SQL.append("        pro.pro_preco     as preco, \n");
		SQL.append("        pro.usu_id        as idUsuario, \n");
		SQL.append("        pro.pro_foto      as foto, \n");
		SQL.append("        pro.cla_id        as idClasse \n");
		SQL.append("FROM    mercadex.pro_produto pro \n");
		SQL.append("INNER JOIN mercadex.cla_classe cla \n");
		SQL.append("ON      cla.cla_id = pro.cla_id \n");
		SQL.append("WHERE   cla.cla_id = ?");
		
		try {
			conn = super.getConnection();
			stmt = conn.prepareStatement(SQL.toString());
			
			stmt.setInt(count++, classe.getId());
			
			resultSet = stmt.executeQuery();
			
			while (resultSet.next()) {
				Produto produto = new Produto();
				
				produto.setId(resultSet.getInt("id"));
				produto.setDescricao(resultSet.getString("descricao"));
				produto.setPreco(resultSet.getDouble("preco"));
				
				retorno.add(produto);
			} 
			
			
		} catch (SQLException e) {
			throw new ErroGeralException();
		}
		
		if (retorno.isEmpty()) {
			throw new ClasseVaziaException(classe);
		}
		
		return retorno;
	}
	
	public List<Produto> obterProdutosPorVendedor(Usuario usuario) throws UsuarioSemProdutoException, ErroGeralException {
		List<Produto> retorno = new ArrayList<Produto>();
		Integer count = 1;
		Connection conn = null;
		StringBuffer SQL = new StringBuffer();
		PreparedStatement stmt = null;
		ResultSet resultSet;
		
		SQL.append("SELECT  pro.pro_id        as id, \n");
		SQL.append("        pro.pro_shortdesc as descricao, \n");
		SQL.append("        pro.pro_preco     as preco, \n");
		SQL.append("        pro.usu_id        as idUsuario, \n");
		SQL.append("        pro.pro_foto      as foto, \n");
		SQL.append("        pro.cla_id        as idClasse \n");
		SQL.append("FROM    mercadex.pro_produto pro \n");
		SQL.append("INNER JOIN mercadex.usu_usuario usu \n");
		SQL.append("ON      usu.usu_id = pro.usu_id \n");
		SQL.append("WHERE   usu.usu_id = ?");
		
		try {
			conn = super.getConnection();
			stmt = conn.prepareStatement(SQL.toString());
			
			stmt.setInt(count++, usuario.getId());
			
			resultSet = stmt.executeQuery();
			
			while (resultSet.next()) {
				Produto produto = new Produto();
				
				produto.setId(resultSet.getInt("id"));
				produto.setDescricao(resultSet.getString("descricao"));
				produto.setPreco(resultSet.getDouble("preco"));
				
				retorno.add(produto);
			} 
			
			
		} catch (SQLException e) {
			throw new ErroGeralException();
		}
		
		if (retorno.isEmpty()) {
			throw new UsuarioSemProdutoException(usuario);
		}
		
		return retorno;
	}
	
	public Produto obterdetalhesProduto(Produto produto) throws ProdutoNaoEncontradoException, ErroGeralException {
		Integer count = 1;
		Connection conn = null;
		StringBuffer SQL = new StringBuffer();
		PreparedStatement stmt = null;
		ResultSet resultSet;
		
		SQL.append("SELECT  pro.pro_id        as id, \n");
		SQL.append("        pro.pro_shortdesc as descricao, \n");
		SQL.append("        pro.pro_fulldesc as descricaoCompleta, \n");
		SQL.append("        pro.pro_preco     as preco, \n");
		SQL.append("        pro.usu_id        as idUsuario, \n");
		SQL.append("        pro.pro_foto      as foto, \n");
		SQL.append("        pro.cla_id        as idClasse \n");
		SQL.append("FROM    mercadex.pro_produto pro \n");
		SQL.append("WHERE   pro.pro_id = ?");
		
		try {
			conn = super.getConnection();
			stmt = conn.prepareStatement(SQL.toString());
			
			stmt.setInt(count++, produto.getId());
			
			resultSet = stmt.executeQuery();
			
			if (resultSet.next()) {
							
				produto.setId(resultSet.getInt("id"));
				produto.setDescricao(resultSet.getString("descricao"));
				produto.setPreco(resultSet.getDouble("preco"));
				produto.setDescricaoCompleta(resultSet.getString("descricaoCompleta"));
				produto.setVendedor(new Usuario(resultSet.getInt("idUsuario")));
				produto.setClasse(new Classe(resultSet.getInt("idClasse")));
				//produto.setFoto((resultSet.getBinaryStream("foto")));
				
			} else {
				throw new ProdutoNaoEncontradoException(produto);
			}
			
			
		} catch (SQLException e) {
			throw new ErroGeralException();
		}
		return produto;
	}
	
	public InputStream obterFotoProduto(Produto produto) throws ProdutoNaoEncontradoException, ErroGeralException {
		Integer count = 1;
		Connection conn = null;
		StringBuffer SQL = new StringBuffer();
		PreparedStatement stmt = null;
		ResultSet resultSet;
		
		SQL.append("SELECT  pro.pro_foto      as foto \n");
		SQL.append("FROM    mercadex.pro_produto pro \n");
		SQL.append("WHERE   pro.pro_id = ?");
		
		try {
			conn = super.getConnection();
			stmt = conn.prepareStatement(SQL.toString());
			
			stmt.setInt(count++, produto.getId());
			
			resultSet = stmt.executeQuery();
			
			if (resultSet.next()) {
							
				return resultSet.getBinaryStream("foto");
				
			} else {
				throw new ProdutoNaoEncontradoException(produto);
			}
			
			
		} catch (SQLException e) {
			throw new ErroGeralException();
		}
	}
	
	public void excluirProduto(Produto produto) throws ErroGeralException {
		Integer count = 1;
		Connection conn = null;
		StringBuffer SQL = new StringBuffer();
		PreparedStatement stmt = null;
		
		SQL.append("DELETE \n");
		SQL.append("FROM    mercadex.pro_produto \n");
		SQL.append("WHERE   mercadex.pro_produto.pro_id = ?");
		
		try {
			conn = super.getConnection();
			stmt = conn.prepareStatement(SQL.toString());
			
			stmt.setInt(count++, produto.getId());
			
			stmt.execute();
			
		} catch (SQLException e) {
			throw new ErroGeralException();
		}
	}
}
